package com.ybkj.daijia.api.apirest.v4;

import com.ybkj.daijia.OrderConfirmLocs;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.api.driver.transport.ResultTransport;
import com.ybkj.daijia.api.util.ErrorConstantV4;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.server.errand.SelectPrice;
import com.ybkj.daijia.server.event.model.OrderEmployHasPayEvent;
import com.ybkj.daijia.server.event.model.OrderPassengerHasPayEvent;
import com.ybkj.daijia.server.event.model.freight.FreightMemberRebateEvent;
import com.ybkj.daijia.server.event.model.freight.FreightOrderAcceptEvent;
import com.ybkj.daijia.server.event.model.freight.FreightOrderArriveEvent;
import com.ybkj.daijia.server.event.model.freight.FreightOrderCancelEvent;
import com.ybkj.daijia.server.event.model.freight.FreightOrderConfirmEvent;
import com.ybkj.daijia.server.freight.Order;
import com.ybkj.daijia.server.freight.Order.PayTypeDetails;
import com.ybkj.daijia.server.freight.Truck;
import com.ybkj.daijia.server.freight.TruckType;
import com.ybkj.daijia.server.mc.Enterprise;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.model.Area;
import com.ybkj.daijia.server.model.ChargeStartDistance;
import com.ybkj.daijia.server.model.ChargeStartTime;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.Driver;
import com.ybkj.daijia.server.model.DriverRefuseRecord;
import com.ybkj.daijia.server.model.FirstOrderPassenger;
import com.ybkj.daijia.server.model.OrderLocation;
import com.ybkj.daijia.server.model.OrderLocationMany;
import com.ybkj.daijia.server.sales.Coupon;
import com.ybkj.daijia.server.sales.CouponRule;
import com.ybkj.daijia.server.service.AreaService;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.CouponService;
import com.ybkj.daijia.server.service.DriverRefuseRecordService;
import com.ybkj.daijia.server.service.DriverService;
import com.ybkj.daijia.server.service.FirstOrderPassengerService;
import com.ybkj.daijia.server.service.FreightService;
import com.ybkj.daijia.server.service.MemberService;
import com.ybkj.daijia.server.service.OrderLocationManyService;
import com.ybkj.daijia.server.service.SmsService;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

@Controller("ApiFreightProcessControllerV4")
@RequestMapping(value = "api/freight/v4")
public class FreightProcessController {

    private static final Logger logger = LoggerFactory.getLogger(FreightProcessController.class);
    @Autowired
    private SettingUtils settingUtils;
    @Autowired
    private FreightService freightService;
    @Autowired
    private AreaService areaService;
    @Autowired
    private DriverService driverService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private DriverRefuseRecordService driverRefuseRecordService;
    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;
    @Autowired
    private OrderLocationManyService orderLocationManyService;
    @Autowired
    private SmsService smsService;
    @Autowired
    private FirstOrderPassengerService firstOrderPassengerService;

    /**
     * 根据距离和时间按照公司的收费标准预估订单价格
     *
     * @return
     */
    @RequestMapping(value = "getPrice", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> getPrice(
        @RequestParam("driverId") Long driverId,
        @RequestParam("mileage") Double mileage1,
        @RequestParam("time") Long time1) {
        Map<String, Object> result = new HashMap<String, Object>();
        BigDecimal money = BigDecimal.ZERO;
        try {

            Driver driver = driverService.findOne(driverId);
            Long truckId = driver.getTruckId();
            if (truckId == null) {
                result.put("code", -4);
                result.put("message", "该服务人员没有货运车辆");
                return result;
            }
            Truck truck = freightService.findTruck(truckId);
            if (truck == null) {
                result.put("code", -4);
                result.put("message", "该服务人员没有货运车辆");
                return result;
            }
            TruckType truckType = freightService
                .findTruckByTruckTypeIdAndCompanyId(truck.getTruckTypeId(), truck.getCompanyId());
            Area area = areaService.findOneWithCharge(truckType.getAreaId());

            SelectPrice selectPrice = new SelectPrice();
            selectPrice.setPrice(time1, mileage1, area, null, 0D);
            money = selectPrice.shouldCash;
            BigDecimal startPrice = selectPrice.qbCost;
            BigDecimal mileagePrice = selectPrice.disCost;
            BigDecimal travelTimePrice = selectPrice.travalTimeCost;
            ChargeStartTime price = selectPrice.getPrice();
            StringBuilder builder = new StringBuilder();
            builder.append("起步价:" + startPrice + "元\n");
            List<ChargeStartDistance> distances = price.getChargeStartDistances();

            if (distances != null && distances.size() != 0) {
                for (ChargeStartDistance d : distances) {
                    builder.append(
                        d.getStartdistance() + "公里到" + d.getDistance() + "公里内,加收" + d.getMoney()
                            + "元");
                    builder.append("\n");
                }
            }

            builder.append("超过" + price.getQblc() + "公里");
            builder.append("以后每" + price.getDjglUnit() + "公里");
            builder.append("加收" + price.getDjglCost() + "元");
            if (price.getDjglThresholdt() != 0) {
                builder.append("(不足" + price.getDjglThresholdt() + "公里不计费)");
            }
            builder.append("\n");
            builder.append("起步后" + price.getQbsj() + "分钟内不收费");
            builder.append("以后每" + price.getDjsjUnit() + "分钟");
            builder.append("加收" + price.getDjsjCost() + "元");
            if (price.getDjsjThresholdt() != 0) {
                builder.append("(不足" + price.getDjsjThresholdt() + "分钟不收费)");
            }
            builder.append("\n");
            builder.append("免费等候" + price.getMfdhsj() + "分钟");
            BigDecimal bigDecimal = price.getDhsjAtonceCost();

            if (bigDecimal.compareTo(BigDecimal.ZERO) == 1) {
                builder.append("到达则立即加收" + price.getDhsjAtonceCost() + "元");
            }
            builder.append("后每" + price.getDhsjUnit() + "分钟");
            builder.append("加收" + price.getDhsjCost() + "元");
            if (price.getDhsjThresholdt() != 0) {
                builder.append("(低于" + price.getDhsjThresholdt() + "分钟不计费)");
            }
            builder.append("\n");
            if (StringUtils.isNotBlank(area.getMemo())) {
                builder.append("备注:" + area.getMemo());
            }
            result.put("success", true);
            result.put("pay_detail", builder.toString());
            result.put("money", money != null ? money : 0.0);
            result.put("startPrice", startPrice != null ? startPrice : 0.0);          //起步价
            result.put("mileagePrice", mileagePrice != null ? mileagePrice : 0.0);        //行驶里程费用
            result.put("travelTimePrice", travelTimePrice != null ? travelTimePrice : 0.0); //服务时间费用
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", 0);
            map.put("data", result);
            map.put("message", "请求成功");
            return map;

        } catch (Exception e) {
            e.printStackTrace();
            result.put("code", 500);
            result.put("message", e.getMessage());
            return result;
        }

    }

    @RequestMapping(value = "completeTaskData", method = RequestMethod.GET)
    public @ResponseBody
    ResultTransport completeTaskData(Long orderId) {

        logger.error("recv orderId:{}", orderId);

        if (null == orderId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = freightService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_STATUS_ERROR);
        }

        Driver driver = driverService.findOne(order.getEmployId());
        if (null == driver) {
            return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
        }

        Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PASSENGER_NOT_EXISTS);
        }

        try {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("orderId", order.getId());
            map.put("orderNumber", order.getOrderNo());
            map.put("orderType", "freight");
            map.put("passengerPhone", passenger.getPhone());
            map.put("passengerName", passenger.getName());
            map.put("passengerType", passenger.getTypeStr());

            //等级
            map.put("passengerGrade", passenger.getGrade_name());

            Company orderCompany = companyService.findOne(order.getCompanyId());
            map.put("orderCompanyName", orderCompany.getAbbreviation());

            Company passengerCompany = companyService.findOne(passenger.getCompanyId());
            map.put("passengerCompanyName", passengerCompany.getAbbreviation());

            if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                map.put("overdraw", passenger.isAllowOverdraw());
                map.put("virtual", passenger.getDrawMoney().add(passenger.getNodrawMoney())
                    .setScale(2, BigDecimal.ROUND_HALF_UP));
            } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                map.put("overdraw", enterprise.isAllowOverdraw());
                map.put("virtual", enterprise.getDrawMoney().add(enterprise.getNodrawMoney())
                    .setScale(2, BigDecimal.ROUND_HALF_UP));
            }

            //优惠券
            if (null != order.getCouponId()) {
                Coupon coupon = couponService.findOne(order.getCouponId());
                if (null != coupon) {
                    CouponRule couponRule = coupon.getCouponRule();
                    if (couponRule.getType().equals(CouponRule.TYPE_DEDUCTION)) {
                        map.put("couponMoney", couponRule.getMoney());
                    } else if (couponRule.getType().equals(CouponRule.TYPE_DISCOUNT)) {
                        map.put("discount", couponRule.getDiscount());
                    }
                    map.put("coupon_type", CouponRule.TYPE_DISCOUNT);
                }
            }

            //首单免费
            Long completeTimes = firstOrderPassengerService
                .selectAll(passenger.getId(), FirstOrderPassenger.FREE_ORDERTYPE_FREIGHT);
            if (completeTimes > 0) {
                map.put("firstFree", false);
            } else {
                map.put("firstFree", true);
            }

            map.put("employId", driver.getId());
            map.put("employName", driver.getName());
            map.put("employPhone", driver.getPhone());

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData(map);
            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    @RequestMapping(value = "checkTask", method = RequestMethod.GET)
    public @ResponseBody
    ResultTransport checkTask(Long orderId) {

        if (null == orderId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = freightService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        try {

            boolean finished = false;
            if (order.getStatus().equals(Order.ORDER_STATUS_OK)) {
                finished = true;
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData(finished);
            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }


    @RequestMapping(value = "confirmTask", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport confirmTask(
        Long orderId, BigDecimal realCash, BigDecimal guoluMoney, BigDecimal yuanchengMoney,
        BigDecimal otherMoney, Double mileage, Integer waitedTime, Integer travelTime,
        @RequestParam(required = false, value = "startPrice") BigDecimal startPrice,
        @RequestParam(required = false, value = "mileagePrice") BigDecimal mileagePrice,
        @RequestParam(required = false, value = "runTimePrice") BigDecimal runTimePrice,
        @RequestParam(required = false, value = "waitPrice") BigDecimal waitPrice,
        @RequestParam(required = false, value = "memo") String memo,
        @RequestParam(required = false, value = "jsonLocs") String jsonLocs) {

        return confirmTaskFunction(orderId, realCash, guoluMoney, yuanchengMoney, otherMoney,
            mileage, waitedTime, travelTime,
            startPrice, mileagePrice, runTimePrice, waitPrice, memo, null, null, jsonLocs, null);
    }

    @RequestMapping(value = "confirmTaskJsonFile", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport confirmTaskJsonFile(
        Long orderId, BigDecimal realCash, BigDecimal guoluMoney, BigDecimal yuanchengMoney,
        BigDecimal otherMoney, Double mileage, Integer waitedTime, Integer travelTime,
        @RequestParam(required = false, value = "startPrice") BigDecimal startPrice,
        @RequestParam(required = false, value = "mileagePrice") BigDecimal mileagePrice,
        @RequestParam(required = false, value = "runTimePrice") BigDecimal runTimePrice,
        @RequestParam(required = false, value = "waitPrice") BigDecimal waitPrice,
        @RequestParam(required = false, value = "memo") String memo,
        @RequestParam(required = false, value = "justKilometres") Double justKilometres,
        @RequestParam(required = false, value = "justMoney") BigDecimal justMoney,
        @RequestParam(required = false, value = "jsonLocs") String jsonLocs,
        @RequestParam(required = false, value = "jsonLocFile") MultipartFile jsonLocFile) {

        return confirmTaskFunction(orderId, realCash, guoluMoney, yuanchengMoney, otherMoney,
            mileage, waitedTime, travelTime,
            startPrice, mileagePrice, runTimePrice, waitPrice, memo, justKilometres, justMoney,
            jsonLocs, jsonLocFile);

    }

    private ResultTransport confirmTaskFunction(
        Long orderId, BigDecimal realCash,
        BigDecimal guoluMoney, BigDecimal yuanchengMoney, BigDecimal otherMoney,
        Double mileage, Integer waitedTime, Integer travelTime,
        BigDecimal startPrice, BigDecimal mileagePrice, BigDecimal runTimePrice,
        BigDecimal waitPrice, String memo, Double justKilometres, BigDecimal justMoney,
        String jsonLocs, MultipartFile jsonLocFile) {

        logger.error("recv orderId:{},realCash:{},guoluMoney:{},yuanchengMoney:{},otherMoney:{},"
                + "mileage:{},waitedTime:{},travelTime:{},startPrice:{},mileagePrice:{},runTimePrice:{},waitPrice:{}",
            orderId, realCash, guoluMoney, yuanchengMoney, otherMoney, mileage, waitedTime,
            travelTime, startPrice, mileagePrice, runTimePrice, waitPrice);

        if (null == orderId || null == realCash || null == mileage || null == waitedTime
            || null == travelTime) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = freightService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_STATUS_ERROR);
        }

        if (order.getTreatment()) {
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData("waitfinish");
            return instance;
        }

        try {
            order.setGuoluMoney(guoluMoney);
            order.setYuanchengMoney(yuanchengMoney);
            order.setOtherMoney(otherMoney);
            order.setRealPay(realCash.doubleValue());

            //优惠券
            Coupon coupon = null;
            BigDecimal coupon_hasPayed = BigDecimal.ZERO;
            Double discount = null;
            if (null != order.getCouponId()) {
                coupon = couponService.findOne(order.getCouponId());
                if (null != coupon) {
                    if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DEDUCTION)) {
                        coupon_hasPayed = coupon.getCouponRule().getMoney();
                    } else if (coupon.getCouponRule().getType().equals(CouponRule.TYPE_DISCOUNT)) {
                        discount = coupon.getCouponRule().getDiscount();
                        coupon_hasPayed = realCash.subtract(order.getGuoluMoney()).multiply(
                            new BigDecimal(1)
                                .subtract(new BigDecimal(discount).divide(new BigDecimal(10))))
                            .setScale(0, BigDecimal.ROUND_DOWN);
                    }
                }
            }

            order.setCouponMoney(coupon_hasPayed);
            if (coupon_hasPayed.doubleValue() > 0 && null == order.getPrePayTypeDetail()) {
                order.setPrePayTypeDetail(PayTypeDetails.coupon);
            }
            order.setDiscount(discount);
            order.setMemo(memo);
            BigDecimal m = new BigDecimal(mileage);
            double df = m.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
            order.setMileage(df);
            order.setWaitTime(waitedTime);
            order.setRunTime(travelTime);

            if (null != startPrice) {
                order.setStartPrice(startPrice.doubleValue());
            }
            if (null != mileagePrice) {
                order.setMileagePrice(mileagePrice.doubleValue());
            }
            if (null != runTimePrice) {
                order.setRunTimePrice(runTimePrice.doubleValue());
            }
            if (null != waitPrice) {
                order.setWaitCost(waitPrice.doubleValue());
            }
            if (null != justKilometres) {
                order.setJustKilometres(justKilometres);
            }
            if (null != justMoney) {
                order.setJustMoney(justMoney);
            }

            order.setTreatment(true);
            Result<Order> result = freightService.confirmTask(order, null);

            Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
            if (StringUtils.isNotBlank(memo)) {
                passenger.setPlateNumber(memo);
                memberService.updatePassenger(passenger);
            }

            if (result.isSuccess()) {
                //保存位置
                if (null != jsonLocFile) {
                    jsonLocs = OrderConfirmLocs.locs(jsonLocFile);
                }

                if (StringUtils.isNotBlank(jsonLocs)) {
                    OrderLocationMany orderLocationMany = new OrderLocationMany();
                    orderLocationMany.setOrderId(orderId);
                    orderLocationMany.setOrderType(OrderLocation.OrderType.freight);
                    orderLocationMany.setJsonLocs(jsonLocs);
                    orderLocationManyService.save(orderLocationMany);
                }

                BigDecimal money = new BigDecimal(order.getRealPay());//还需支付的钱
                money = money.subtract(order.getGuoluMoney());
                money = money.subtract(coupon_hasPayed);
                if (money.doubleValue() < 0) {
                    money = BigDecimal.ZERO;
                }
                money = money.add(order.getGuoluMoney());

                Driver driver = driverService.findOne(order.getEmployId());
                freightService.confirmTaskV4(order, driver);

                if (money.doubleValue() <= 0) {
                    //直接结算
                    result = freightService
                        .completeTaskNewV3(order, passenger, driver, "clickComplete", null);

                    if (result.isSuccess()) {
                        OrderEmployHasPayEvent orderEmployHasPayEvent = new OrderEmployHasPayEvent(
                            passenger, order.getId(), "freight");
                        applicationEventMulticaster.multicastEvent(orderEmployHasPayEvent);

                        ResultTransport instance = ResultTransport
                            .getErrorBy(ErrorConstantV4.SUCCESS);
                        instance.setData("hasfinished");
                        return instance;
                    } else {
                        ResultTransport instance = ResultTransport
                            .getErrorBy(ErrorConstantV4.SERVER_ERROR);
                        return instance;
                    }
                } else {
                    //进入确认页面
                    //客户端提醒付费推送

                    FreightOrderConfirmEvent freightOrderConfirmEvent = new FreightOrderConfirmEvent(
                        order);
                    applicationEventMulticaster.multicastEvent(freightOrderConfirmEvent);

                    ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
                    instance.setData("waitfinish");
                    return instance;
                }
            } else {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
                return instance;
            }
        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
            return instance;
        }

    }

    @RequestMapping(value = "finishTask", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport finishTask(Long orderId, String payType, String who) {

        logger.error("recv orderId:{},payType{}", orderId, payType);

        if (null == orderId || StringUtils.isBlank(payType)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        if (!"helppay".equals(payType) && !"sign".equals(payType) && !"balance".equals(payType)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = freightService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        if (!order.getStatus().equals(Order.ORDER_STATUS_ZHIXING)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_STATUS_ERROR);
        }

        if (!order.getTreatment()) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_CONFIRM);
        }

        Setting setting = settingUtils.get();

        Double afterPayMoney = 0d;
        if (null != order.getPrePayTypeDetail()) {
            if (order.getPrePayTypeDetail().equals(PayTypeDetails.coupon)) {
                afterPayMoney = order.getRealPay() - order.getCouponMoney().doubleValue();
            }
        } else {
            afterPayMoney = order.getRealPay();
        }

        Driver driver = driverService.findOne(order.getEmployId());
        if ("helppay".equals(payType)) {//如果是代付，服务人员收到现金，余额减钱
            if (afterPayMoney.doubleValue() >= 10000) {
                return ResultTransport.getErrorBy(ErrorConstantV4.HELP_PAY_MONEY_TOOLARGE);
            }
            if (null == driver) {
                return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
            }
            if (!setting.isAllowHelppayNe()) {
                if (driver.getVirtual().doubleValue() < (afterPayMoney.doubleValue())) {
                    return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_MONEY_NOT_ENOUGH);
                }
            }
        }

        Passenger passenger = memberService.findOnePassenger(order.getPassengerId());
        if (null != passenger) {
            if ("sign".equals(payType)) {//签单支付
                if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                    if (!passenger.isAllowOverdraw()) {
                        return ResultTransport.getErrorBy(ErrorConstantV4.PASSENGER_NOT_ALLOW_SIGN);
                    }
                } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                    Enterprise enterprise = memberService
                        .findOneEnterprise(passenger.getEnterprise_id());
                    if (!enterprise.isAllowOverdraw()) {
                        return ResultTransport.getErrorBy(ErrorConstantV4.PASSENGER_NOT_ALLOW_SIGN);
                    }
                }
            } else if ("balance".equals(payType)) {//余额支付
                if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                    BigDecimal shengyuMoney = BigDecimal.ZERO;
                    shengyuMoney = shengyuMoney.add(passenger.getNodrawMoney());
                    if (passenger.getDrawMoney().doubleValue() > 0) {
                        shengyuMoney = shengyuMoney.add(passenger.getDrawMoney());
                    }
                    if (shengyuMoney.doubleValue() < afterPayMoney) {
                        return ResultTransport
                            .getErrorBy(ErrorConstantV4.PASSENGER_MONEY_NOT_ENOUGH);
                    }
                } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                    Enterprise enterprise = memberService
                        .findOneEnterprise(passenger.getEnterprise_id());
                    BigDecimal shengyuMoney = BigDecimal.ZERO;
                    shengyuMoney = shengyuMoney.add(enterprise.getNodrawMoney());
                    if (enterprise.getDrawMoney().doubleValue() > 0) {
                        shengyuMoney = shengyuMoney.add(enterprise.getDrawMoney());
                    }
                    if (shengyuMoney.doubleValue() < afterPayMoney) {
                        return ResultTransport
                            .getErrorBy(ErrorConstantV4.PASSENGER_MONEY_NOT_ENOUGH);
                    }
                }
            }
        }

        try {

            Result<Order> result = freightService
                .completeTaskNewV3(order, passenger, driver, "clickPay", payType);

            if (result.isSuccess()) {
                if (StringUtils.isNotBlank(who) && who.equals("passenger")) {
                    OrderPassengerHasPayEvent orderPassengerHasPayEvent = new OrderPassengerHasPayEvent(
                        driver, order.getId(), "freight");
                    applicationEventMulticaster.multicastEvent(orderPassengerHasPayEvent);
                } else {
                    OrderEmployHasPayEvent orderEmployHasPayEvent = new OrderEmployHasPayEvent(
                        passenger, order.getId(), "freight");
                    applicationEventMulticaster.multicastEvent(orderEmployHasPayEvent);
                }

                if (null != passenger) {
                    FreightMemberRebateEvent memberRebateEvent = new FreightMemberRebateEvent(
                        passenger, order, new BigDecimal(order.getRealPay()), 1);
                    applicationEventMulticaster.multicastEvent(memberRebateEvent);
                }

                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
                return instance;

            } else {
                if (result.getErrorcode()
                    .equals(String.valueOf(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED.getCode()))) {
                    ResultTransport instance = ResultTransport
                        .getErrorBy(ErrorConstantV4.ORDER_HAS_BEEN_FINISHED);
                    return instance;
                } else {
                    ResultTransport instance = ResultTransport
                        .getErrorBy(ErrorConstantV4.SERVER_ERROR);
                    return instance;
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
            return instance;
        }

    }

    @RequestMapping(value = "pushOrderAccept")
    public @ResponseBody
    ResultTransport pushOrderAccept(Long orderId, Long employId) {

        if (null == orderId || null == employId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Driver driver = driverService.findOne(employId);

        if (null == driver) {
            return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
        }

        Order order = freightService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        try {

            driverService
                .updateStatusAndJobStatus(Driver.DRIVER_BUSY, Driver.DRIVER_JOBSTATUS_FREIGHT,
                    order.getEmployId());

            FreightOrderAcceptEvent freightOrderAcceptEvent = new FreightOrderAcceptEvent(order,
                driver);
            applicationEventMulticaster.multicastEvent(freightOrderAcceptEvent);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            instance.setData(orderId);

            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    @RequestMapping(value = "pushRefuseOrder")
    public @ResponseBody
    ResultTransport pushRefuseOrder(Long orderId, Long employId, String cause) {

        if (null == orderId || null == employId || StringUtils.isBlank(cause)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Driver driver = driverService.findOne(employId);

        if (null == driver) {
            return ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_NOT_EXISTS);
        }

        Order order = freightService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        try {
            if (driver.getStatus() != Driver.DRIVER_OFFLINE) {
                driverService.updateStatusAndJobStatus(Driver.DRIVER_ONLINE, null, driver.getId());
            }

            //拒绝工单记录
            DriverRefuseRecord driverRefuseRecord = new DriverRefuseRecord();
            driverRefuseRecord.setEmployId(driver.getId());
            driverRefuseRecord.setEmployRealName(driver.getRealname());
            driverRefuseRecord.setEmployUserName(driver.getUsername());
            driverRefuseRecord.setEmployPhone(driver.getPhone());
            driverRefuseRecord.setHappend(new Date());
            driverRefuseRecord.setOrderId(order.getId());
            driverRefuseRecord.setOrderNumber(order.getOrderNo());
            driverRefuseRecord.setOrderCompanyId(order.getCompanyId());
            driverRefuseRecord.setMemo(cause);
            driverRefuseRecord.setOrderType(DriverRefuseRecord.OrderType.freight);
            driverRefuseRecordService.save(driverRefuseRecord);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    @RequestMapping(value = "pushOrderCancel")
    public @ResponseBody
    ResultTransport pushOrderCancel(Long orderId, boolean isDriver, String cause) {

        if (null == orderId || StringUtils.isBlank(cause)) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = freightService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        try {

            if (order.getEmployId() != null) {
                Driver dr = driverService.findOne(order.getEmployId());
                if (dr.getStatus() != Driver.DRIVER_OFFLINE) {
                    driverService.updateStatusAndJobStatus(Driver.DRIVER_ONLINE, null, dr.getId());
                }
            }
            if (isDriver) {
                FreightOrderCancelEvent freightOrderCancelEvent = new FreightOrderCancelEvent(order,
                    null, "driverCancel");
                applicationEventMulticaster.multicastEvent(freightOrderCancelEvent);
            } else {
                Driver driver = driverService.findOne(order.getEmployId());
                FreightOrderCancelEvent freightOrderCancelEvent = new FreightOrderCancelEvent(order,
                    driver, "customerCancel");
                applicationEventMulticaster.multicastEvent(freightOrderCancelEvent);
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            return instance;

        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }

    @RequestMapping(value = "pushWait")
    public @ResponseBody
    ResultTransport pushWait(Long orderId) {

        if (null == orderId) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PARAM_ERROR);
        }

        Order order = freightService.findOne(orderId);

        if (null == order) {
            return ResultTransport.getErrorBy(ErrorConstantV4.ORDER_NOT_EXISTS_ERROR);
        }

        Passenger passenger = memberService.findOnePassenger(order.getPassengerId());

        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstantV4.PASSENGER_NOT_EXISTS);
        }

        try {
            FreightOrderArriveEvent freightOrderArriveEvent = new FreightOrderArriveEvent(order,
                passenger);
            applicationEventMulticaster.multicastEvent(freightOrderArriveEvent);

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
            return instance;
        } catch (Exception e) {
            e.printStackTrace();
            return ResultTransport.getErrorBy(ErrorConstantV4.SERVER_ERROR);
        }
    }


}
